/**
 * @MessageDecoder.java  COPYRIGHT xiaojian
 * 
 * Created on 2017年7月14日 下午2:31:06
 */
package xj.toolkit.access;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ByteToMessageDecoder;
import xiaojian.toolkit.bean.CommonsHeader;
import xiaojian.toolkit.util.ByteUtils;
import xj.toolkit.access.AccessHeader;
import xj.toolkit.access.AccessMsgCodeConstants;
import xj.toolkit.access.msg.AccessAckMessage;
import xj.toolkit.access.msg.AccessContentMessage;
import xj.toolkit.access.msg.AccessSynMessage;

/**
 * @author <a href="mailto:cxj2000@gmail.com">xiaojian.cao</a>
 *
 */
public class MessageDecoder extends ByteToMessageDecoder {
	
	private static final Logger logger = LoggerFactory.getLogger(MessageDecoder.class);

	@Override
	protected void decode(ChannelHandlerContext ctx, ByteBuf buffer, List<Object> out) throws Exception {
		CommonsHeader header = new CommonsHeader();
		header.setBasicVer(buffer.readByte());
		header.setPayloadType(buffer.readShort());
		header.setType(buffer.readShort());
		header.setFirstTransaction(buffer.readLong());
		header.setSecondTransaction(buffer.readLong());
		header.setReserved(buffer.readInt());
		header.setMessageCode(buffer.readInt());
		header.setMessageLength(buffer.readInt());

		logger.debug("header-->" + header);
		
		AccessHeader accessHeader = new AccessHeader();
		accessHeader.setSourceModuleId(buffer.readShort());
		accessHeader.setTargetInstanceId(buffer.readShort());
		accessHeader.setTargetModuleId(buffer.readShort());
		accessHeader.setTargetInstanceId(buffer.readShort());
		accessHeader.setReserved(buffer.readInt());

		// -- 如果是ACK信息
		if (header.getMessageCode() == AccessMsgCodeConstants.MSG_CODE_SYN) {
			AccessSynMessage synMessage = new AccessSynMessage();
			synMessage.setAccessHeader(accessHeader);
			synMessage.setCommonHeader(header);

			if (logger.isDebugEnabled()) {
				logger.debug("message[{}].", synMessage);
			}

			out.add(synMessage);
			return;
		}

		final byte[] bytes = new byte[header.getMessageLength() - AccessHeader.HEADER_LENGTH];
		buffer.readBytes(bytes);
		if (logger.isTraceEnabled()) {
			logger.trace("body raw bytes \r\n{}", ByteUtils.bytesAsHexString(bytes, 1024));
		}

		AccessContentMessage message = new AccessContentMessage();
		message.setCommonHeader(header);
		message.setAccessHeader(accessHeader);
		message.setContent(bytes);

		if (logger.isDebugEnabled()) {
			logger.debug("message[{}].", message);
		}

		out.add(message);
	}

}
